package project.newCode.scenegraph;
import java.util.Stack;

import project.hulpPakket.Matrix4f;
import project.hulpPakket.Point3f;
import project.hulpPakket.Scene;
import project.hulpPakket.Vector3f;
import project.newCode.Hitrecord;
import project.newCode.Ray;
import project.newCode.surfaces.Box;
import project.newCode.surfaces.Hittable;
import project.newCode.surfaces.Surface;
import project.newCode.transformations.*;
// What should this class do?
// It should implement the traversing of the scene graph, and accounting for the transformations and suc
public class SceneTraverserHittable extends SceneTraverser implements Hittable{
	private boolean hit = false;
	private Hitrecord rec = new Hitrecord();
	private Hitrecord trec = new Hitrecord();
	private Ray ray = new Ray();
	private float t1 = Float.POSITIVE_INFINITY;
	private float t0 = 0;
	
	public SceneTraverserHittable(Scene s)
	{
		super(s);
	}

	public void traverse() {
		CompositeTransform c = scene.getRoot();
		c.enter(this);
	}


	@Override
	public void visitEntry(LeafShape leafShape) {
		Surface s = scene.getSurface(leafShape.getGeometry());
		s.setMaterial(scene.getMaterial(leafShape.getMaterial()));
		Matrix4f minverse = getLeftProduct();
		Ray r = Matrix4f.transformRay(minverse, this.ray);
		//		System.out.println(minverse.toString()+"\n\n "+r.toString()+"\n\n"+ray.toString()+"\n");
		// First test for the boundingbox
		int temphit = rec.hitCounter+1;
		if(s.boundingbox().hit(r, this.t0, this.t1, this.trec)) {
			if(s.hit(r, this.t0, this.t1, this.trec)) {
				hit = true;
				trec.copyInto(rec);
				t1 = trec.t;
				rec.normal = new Vector3f(Matrix4f.prod3p(minverse.transpose(), new Point3f(trec.normal))).normalise();
				rec.intersection = Point3f.Plus(ray.getOrigin(),ray.getDirection().multiply(t1));
			}
			temphit = temphit+trec.hitCounter;
		}
		rec.hitCounter = temphit;
	}

	public boolean hit(Ray hittingray, double t0, double t1, Hitrecord rec) {
		this.t1 = (float) t1;
		this.t0 = (float) t0;
		this.hit = false;
		this.rec = rec;
		this.trec = new Hitrecord();
		this.ray = hittingray;
		this.matrixStack = new Stack<Transformation>();
		traverse();
		return hit;
	}
	

	public Box boundingbox() {
		// TODO Auto-generated method stub
		return null;
	}


}
